package com.ecoolex.hotel.saas.platform.graphql;

import java.util.List;

import com.ecoolex.framework.common.util.BizAssert;
import com.ecoolex.framework.modularize.api.auth.user.ConsumerMember;
import com.ecoolex.framework.modularize.api.auth.user.ConsumerMemberManager;
import com.ecoolex.framework.modularize.api.service.storage.*;
import com.ecoolex.hotel.saas.enums.PresaleCouponOrderPaymentType;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;

import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.util.Assert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.modularize.api.auth.annotation.PlatformAuthoritativeRegister;
import com.ecoolex.framework.modularize.api.auth.platform.PlatformMemberAuthority;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module;
import com.ecoolex.framework.web.api.graphql2.annotation.MutationField;
import com.ecoolex.framework.web.api.graphql2.annotation.QueryField;
import com.ecoolex.framework.web.api.graphql2.annotation.Source;
import com.ecoolex.framework.web.api.graphql2.annotation.TypeField;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module.Type;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrder;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrderDetail;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrderOperateRecord;
import com.ecoolex.hotel.saas.entity.SalesUser;
import com.ecoolex.hotel.saas.enums.PresaleCouponOrderStatus;
import com.ecoolex.hotel.saas.platform.core.PlatformConstant;
import com.ecoolex.hotel.saas.pojo.QueryPresaleCouponOrderDTO;
import com.ecoolex.hotel.saas.ws.PresaleCouponOrderService;
import com.ecoolex.hotel.saas.ws.SalesUserService;

@GraphQL2Module(type = Type.Platform, description = "预售券订单")
@PlatformAuthoritativeRegister(parentKey = PlatformConstant.AUTH_PROJECT_KEY,
	key = PresaleCouponOrderGraphql.AUTH,
	name = "预售券订单管理",
	remark = "预售券订单管理")
public class PresaleCouponOrderGraphql {

	public static final String AUTH = PlatformConstant.AUTH_PROJECT_KEY + "-PRESALE-COUPON-ORDER";
	
	private static final String AUTH_GET = AUTH + "-GET";
	
	private static final String AUTH_QUERY = AUTH + "-QUERY";
	
	private static final String AUTH_VERIFY = AUTH + "-VERIFY";
	
	private static final String AUTH_CANCEL_VERIFY = AUTH + "-CANCEL-VERIFY";
	
	private static final String AUTH_REFUND = AUTH + "-REFUND";

	private static final String AUTH_CONFIRM_OFFLINE_PAY = AUTH + "-OFFLINE-PAY";
	
	@Reference
	private PresaleCouponOrderService presaleCouponOrderService;
	
	@Autowired
	private StorageService storageService;
	
	@Reference
	private SalesUserService salesUserService;

	@Autowired
	private ConsumerMemberManager consumerMemberManager;

	@TypeField(type = PresaleCouponOrder.class, field = "offlinePayEvidence", description = "线下付款凭证")
	public StorageInfo offlinePayEvidence(@Source PresaleCouponOrder source){
		return storageService.get(source.getOfflinePayEvidence());
	}

	@TypeField(type = PresaleCouponOrder.class, field = "consumerMember", description = "用户详细信息")
	public ConsumerMember consumerMember(@Source PresaleCouponOrder source){
		return consumerMemberManager.getByUserId(source.getUserId());
	}

	@TypeField(type = PresaleCouponOrder.class, field = "canConfirmOfflinePay", description = "能确认线下付款")
	public Boolean canConfirmOfflinePay(@Source PresaleCouponOrder source){
		return 	PresaleCouponOrderStatus.canPay(source.getStatus()) &&
				PresaleCouponOrderPaymentType.OFFLINE_PAY.real().equals(source.getPaymentType());
	}
	
	@TypeField(type = PresaleCouponOrder.class, field = "canRefund", description = "能退款")
	public Boolean canRefund(@Source PresaleCouponOrder source) {
		return PresaleCouponOrderStatus.canRefund(source.getStatus()) && 
			presaleCouponOrderService.presaleCouponCanRefund(source.getOrderId());
	}
	
	@TypeField(type = PresaleCouponOrder.class, field = "canMandatoryRefund", description = "能强制退款")
	public Boolean canMandatoryRefund(@Source PresaleCouponOrder source) {
		return PresaleCouponOrderStatus.canRefund(source.getStatus()) && 
			!presaleCouponOrderService.presaleCouponCanRefund(source.getOrderId());
	}
	
	@TypeField(type = PresaleCouponOrder.class, field = "canVerify", description = "能核销")
	public Boolean canVerify(@Source PresaleCouponOrder source) {
		return PresaleCouponOrderStatus.canVerify(source.getStatus());
	}
	
	@TypeField(type = PresaleCouponOrder.class, field = "canCancelVerify", description = "能撤销核销")
	public Boolean canCancelVerify(@Source PresaleCouponOrder source) {
		return PresaleCouponOrderStatus.canCancelVerify(source.getStatus());
	}
	
	@TypeField(type = PresaleCouponOrder.class, field = "presaleCouponOrderDetail", description = "订单明细")
	public List<PresaleCouponOrderDetail> presaleCouponOrderDetail(@Source PresaleCouponOrder source){
		return presaleCouponOrderService.queryOrderDetail(source.getOrderId());
	}
	
	@TypeField(type = PresaleCouponOrderDetail.class, field = "coverImage", description = "订单明细商品封面图")
	public StorageInfo coverImage(@Source PresaleCouponOrderDetail source) {
		return storageService.get(source.getCoverImage());
	}
	
	@TypeField(type = PresaleCouponOrder.class, field = "salesUser", description = "销售员")
	public SalesUser salesUser(@Source PresaleCouponOrder source) {
		return salesUserService.getByUserIdAndStoreId(source.getUserId(), source.getStoreId());
	}
	
	@TypeField(type = PresaleCouponOrder.class, field = "operateRecordList", description = "订单操作记录")
	public List<PresaleCouponOrderOperateRecord> operateRecordList(@Source PresaleCouponOrder source) {
		return presaleCouponOrderService.operateRecordList(source.getOrderId());
	}
	
	@QueryField(field = "presaleCouponOrder", description = { "预售券订单详情" })
	@PlatformAuthoritativeRegister(parentKey = AUTH, key = AUTH_GET, name = "预售券订单详情")
	public PresaleCouponOrder get(@NonNull Integer orderId, PlatformMemberAuthority user) {
		user.assertAuth(AUTH_GET);
		return presaleCouponOrderService.get(orderId);
	}
	
	@QueryField(field = "presaleCouponOrderList", description = { "预售券订单列表" })
	@PlatformAuthoritativeRegister(parentKey = AUTH, key = AUTH_QUERY, name = "预售券订单列表")
	public Pagination<PresaleCouponOrder> query(@NonNull QueryPresaleCouponOrderDTO query, @NonNull Page page, PlatformMemberAuthority user){
		user.assertAuth(AUTH_QUERY);
		return presaleCouponOrderService.query(query, page);
	}
	
	@MutationField(field = "presaleCouponCodeVerify", description = "预售券码核销")
	@PlatformAuthoritativeRegister(parentKey = AUTH, key = AUTH_VERIFY, name = "预售券码核销")
	public Boolean couponCodeVerify(@NonNull Integer orderId, @NonNull String couponCode, PlatformMemberAuthority user) {
		user.assertAuth(AUTH_VERIFY);
		PresaleCouponOrder order = presaleCouponOrderService.get(orderId);
		Assert.isTrue(Check.notNull(order),ResultCode.VERIFY.build(1), "订单不存在");
		return presaleCouponOrderService.couponCodeVerify(order.getStoreId(), couponCode, user.userName());
	}

	@MutationField(field = "presaleCouponCodeVerifyFast", description = "预售券码快捷核销")
	public Boolean couponCodeVerifyFast(@NonNull Integer storeId, @NonNull String couponCode, PlatformMemberAuthority user) {
		user.assertAuth(AUTH_VERIFY);
		return presaleCouponOrderService.couponCodeVerify(storeId, couponCode, user.userName());
	}
	
	@MutationField(field = "presaleCouponCodeCancelVerify", description = "预售券撤销核销")
	@PlatformAuthoritativeRegister(parentKey = AUTH, key = AUTH_CANCEL_VERIFY, name = "预售券撤销核销")
	public Boolean cancelVerify(@NonNull Integer orderId,@NonNull String remark, PlatformMemberAuthority user) {
		user.assertAuth(AUTH_CANCEL_VERIFY);
		PresaleCouponOrder order = presaleCouponOrderService.get(orderId);
		Assert.isTrue(Check.notNull(order),ResultCode.VERIFY.build(1), "订单不存在");
		return presaleCouponOrderService.cancelVerify(order, remark, user.userName());
	}
	
	@MutationField(field = "refundPresaleCouponOrder", description = "预售券订单退款/强制退款")
	@PlatformAuthoritativeRegister(parentKey = AUTH, key = AUTH_REFUND, name = "预售券订单退款")
	public PresaleCouponOrder refund(@NonNull Integer orderId, PlatformMemberAuthority user) {
		user.assertAuth(AUTH_REFUND);
		PresaleCouponOrder order = presaleCouponOrderService.get(orderId);
		Assert.isTrue(Check.notNull(order),ResultCode.VERIFY.build(1), "订单不存在");
		return presaleCouponOrderService.refund(order, user.userName());
	}

	@MutationField(field = "confirmPresaleCouponOrderOfflinePay", description = "确认预售券订单线下付款")
	@PlatformAuthoritativeRegister(parentKey = AUTH, key = AUTH_CONFIRM_OFFLINE_PAY, name = "确认预售券订单线下付款")
	public PresaleCouponOrder confirmOfflinePay(@NonNull Integer orderId, String offlinePayEvidence, PlatformMemberAuthority user){
		user.assertAuth(AUTH_CONFIRM_OFFLINE_PAY);
		PresaleCouponOrder order = presaleCouponOrderService.get(orderId);
		Assert.isTrue(Check.notNull(order),ResultCode.VERIFY.build(1), "订单不存在");
		BizAssert.isTrue(PresaleCouponOrderStatus.canPay(order.getStatus()) &&
				PresaleCouponOrderPaymentType.OFFLINE_PAY.real().equals(order.getPaymentType()),
				ResultCode.VERIFY.build(2),"订单不能确认线下付款");
		order.setOfflinePayEvidence(offlinePayEvidence);
		return presaleCouponOrderService.confirmOfflinePay(order,user.userName());
	}

	@MutationField(field = "uploadPresaleCouponOrderOfflinePayEvidence", description = { "上传预售券订单线下付款凭证" })
	public StorageInfo uploadHeadImage(@NonNull Upload request, PlatformMemberAuthority user) {
		if (!user.auth(AUTH_CONFIRM_OFFLINE_PAY)) {
			user.notAuthority();
		}
		UploadSource uploadSource = new UploadSource("PresaleCouponOrder", "OfflinePayEvidence");
		UploadLimit uploadLimit = new UploadLimit();
		uploadLimit.setMaxSize(FileSize.MB.byteLength(20));
		uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

		return storageService.upload(request, uploadSource, uploadLimit);
	}
}
